﻿using System;
using System.Windows.Input;
namespace Tfs.OnTheRoad.Commands
{
    /// <summary>
    /// Base Command class
    /// </summary>
    public abstract class BaseCommand : ICommand
    {        
        /// <summary>
        /// Indicates when caseExecuteChanged
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// Method that indicates if canExecute event is setted or not
        /// </summary>
        protected bool CanExecuteChangedSetted
        {
            get
            {
                return CanExecuteChanged != null;
            }
        }

        /// <summary>
        /// Raises the CanExecuteChanged
        /// </summary>
        /// <param name="sender">Event sender</param>
        /// <param name="e">Event related information</param>
        protected void raiseCanExecuteChanged(object sender, EventArgs e)
        {
            if (CanExecuteChangedSetted)
            {
                CanExecuteChanged(sender, e);
            }
        }

        /// <summary>
        /// Performs the navigation to the given URI
        /// </summary>
        /// <param name="path">Relative path to navigate to</param>
        protected void NavigateTo(string path)
        {
            //Just navigation on the easy way. Later we can use MVVM Light Messenger instead
            //But this possibility is so much easier
            ((Tfs.OnTheRoad.App)App.Current).RootFrame.Navigate(new Uri(path, UriKind.Relative));
        }

        /// <summary>
        /// Can this command execute?
        /// </summary>
        /// <param name="parameter">Parameter that could be used to provide some specific information</param>
        /// <returns>Returns True If can execute. Otherwise false</returns>
        public virtual bool CanExecute(object parameter)
        { return true; }

        /// <summary>
        /// Executes the command
        /// </summary>
        /// <param name="parameter">Parameter that could be used to provide some specific information</param>
        public abstract void Execute(object parameter);
    }

    /// <summary>
    /// BaseCommand which can have a ViewModelBase as Type parameter 
    /// </summary>
    /// <typeparam name="ViewModelType"></typeparam>
    public abstract class BaseCommand<ViewModelType> : BaseCommand
        where ViewModelType:GalaSoft.MvvmLight.ViewModelBase
    {
        /// <summary>
        /// Owner ViewType
        /// </summary>
        protected readonly ViewModelType Owner;

        /// <summary>
        /// Creates an instance of the BaseCommand
        /// </summary>
        /// <param name="owner">ViewModel that owns this command</param>
        public BaseCommand(ViewModelType owner):base()
        {
            Owner = owner;
        }

    }
}